// 简单的 Node.js + Express 服务，提供 /api/heroes?name= 搜索接口
const express = require('express');
const cors = require('cors');
const mysql = require('mysql2/promise');
const path = require('path');

const app = express();
app.use(cors());
app.use(express.json());

// 文件上传处理
const multer = require('multer');
const fs = require('fs');

// 确保 img 目录存在（项目根的 img）
const imgDir = path.join(__dirname, '..', 'img');
if (!fs.existsSync(imgDir)) fs.mkdirSync(imgDir, { recursive: true });

// multer 存储配置（保存到项目根的 img）
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, imgDir);
  },
  filename: function (req, file, cb) {
    // 获取武将名作为文件名
    const heroName = req.body.name || 'hero';
    // 保留原始扩展名
    const ext = path.extname(file.originalname) || '.png';
    // 清理文件名中的特殊字符，保留中文和英文
    const cleanName = heroName.replace(/[<>:"/\\|?*]/g, '_');
    // 文件名格式：武将名.扩展名（如：荀彧.png）
    let filename = `${cleanName}${ext}`;
    let fullPath = path.join(imgDir, filename);

    // 如果文件已存在，添加数字后缀（如：荀彧_2.png）
    let counter = 1;
    while (fs.existsSync(fullPath)) {
      counter++;
      filename = `${cleanName}_${counter}${ext}`;
      fullPath = path.join(imgDir, filename);
    }

    cb(null, filename);
  }
});
const upload = multer({ storage });

// 静态服务前端文件（可选）
app.use('/static', express.static(path.join(__dirname, '..')));

// 配置数据库连接池（请根据本地 MySQL 修改）
const dbConfig = {
  host: 'localhost',
  user: 'root',
  password: '123456',
  database: 'sanguosha',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
};

// 创建连接池
const pool = mysql.createPool(dbConfig);

app.get('/api/heroes', async (req, res) => {
  const name = (req.query.name || '').trim();
  const id = req.query.id;
  try{
    // 按 ID 查询
    if(id){
      const [rows] = await pool.execute('SELECT id,name,image_url,faction FROM heroes WHERE id = ?', [id]);
      const out = rows.map(r=>{
        let url = r.image_url || '';
        if(url && !/^https?:\/\//i.test(url) && !/^\//.test(url)) url = '/static/' + url.replace(/^\/+/, '');
        return {...r, image_url: url};
      });
      return res.json({ok:true, data: out});
    }
    // 查询所有或按名称查询
    if(!name){
      const [rows] = await pool.execute('SELECT id,name,image_url,faction FROM heroes LIMIT 50');
      // 前缀处理
      const out = rows.map(r=>{
        let url = r.image_url || '';
        if(url && !/^https?:\/\//i.test(url) && !/^\//.test(url)) url = '/static/' + url.replace(/^\/+/, '');
        return {...r, image_url: url};
      });
      return res.json({ok:true, data: out});
    }
    // 优先精确匹配，如果没有则模糊匹配
    const [exactRows] = await pool.execute('SELECT id,name,image_url,faction FROM heroes WHERE name = ? LIMIT 1', [name]);
    if(exactRows.length > 0){
      const out = exactRows.map(r=>{
        let url = r.image_url || '';
        if(url && !/^https?:\/\//i.test(url) && !/^\//.test(url)) url = '/static/' + url.replace(/^\/+/, '');
        return {...r, image_url: url};
      });
      return res.json({ok:true, data: out});
    }

    // 没有精确匹配时进行模糊匹配
    const [rows] = await pool.execute('SELECT id,name,image_url,faction FROM heroes WHERE name LIKE ? LIMIT 50', [`%${name}%`]);
    const out = rows.map(r=>{
      let url = r.image_url || '';
      if(url && !/^https?:\/\//i.test(url) && !/^\//.test(url)) url = '/static/' + url.replace(/^\/+/, '');
      return {...r, image_url: url};
    });
    return res.json({ok:true, data: out});
  }catch(err){
    console.error(err);
    return res.status(500).json({ok:false, error: err.message});
  }
});

// 新增武将（含图片上传）
// 接受 multipart/form-data: fields: name, faction; file: image
app.post('/api/heroes', upload.single('image'), async (req, res) => {
  const { name, faction } = req.body || {};
  if (!name) return res.status(400).json({ ok: false, error: 'name is required' });

  // 如果上传了文件，保存的相对路径应为 img/xxx
  let imageUrl = '';
  if (req.file && req.file.filename) {
    // 存为相对于项目根的路径，例如 img/xxx.png
    imageUrl = `img/${req.file.filename}`;
  }

  try{
    const sql = 'INSERT INTO heroes (name, image_url, faction, created_at, updated_at) VALUES (?, ?, ?, NOW(), NOW())';
    const [result] = await pool.execute(sql, [name, imageUrl, faction || null]);
    // 返回新增的行 ID，并且规范化返回的 image_url（如果是相对路径则前缀 /static/）
    let returnedUrl = imageUrl || '';
    if(returnedUrl && !/^https?:\/\//i.test(returnedUrl) && !/^\//.test(returnedUrl)) returnedUrl = '/static/' + returnedUrl.replace(/^\/+/, '');
    return res.json({ ok: true, id: result.insertId, image_url: returnedUrl });
  }catch(err){
    console.error(err);
    return res.status(500).json({ ok: false, error: err.message });
  }
});

// 房间管理 API
// 获取所有房间
app.get('/api/rooms', async (req, res) => {
  try{
    const [rows] = await pool.execute('SELECT * FROM rooms ORDER BY created_at DESC LIMIT 50');
    return res.json({ok: true, data: rows});
  }catch(err){
    console.error(err);
    return res.status(500).json({ok: false, error: err.message});
  }
});

// 获取单个房间信息（包含武将列表）
app.get('/api/rooms/:id', async (req, res) => {
  const { id } = req.params;
  try{
    // 获取房间基本信息
    const [roomRows] = await pool.execute('SELECT * FROM rooms WHERE id = ?', [id]);
    if(roomRows.length === 0) return res.status(404).json({ok: false, error: 'Room not found'});

    const room = roomRows[0];

    // 获取房间的武将列表
    const [heroRows] = await pool.execute(
      'SELECT hero_id, position FROM room_heroes WHERE room_id = ? ORDER BY position ASC',
      [id]
    );

    // 构建武将数组（按位置排序）
    room.heroes = heroRows.map(row => row.hero_id);

    return res.json({ok: true, data: room});
  }catch(err){
    console.error(err);
    return res.status(500).json({ok: false, error: err.message});
  }
});

// 创建房间
app.post('/api/rooms', async (req, res) => {
  const { id, creator_id, mode, max_players } = req.body || {};
  if (!id || !mode) return res.status(400).json({ ok: false, error: 'id and mode are required' });

  try{
    const sql = 'INSERT INTO rooms (id, creator_id, mode, status, max_players, current_players, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())';
    await pool.execute(sql, [id, creator_id || '', mode, '等待中', max_players || 8, 1]);
    return res.json({ ok: true, id });
  }catch(err){
    console.error(err);
    return res.status(500).json({ ok: false, error: err.message });
  }
});

// 加入房间
app.put('/api/rooms/:id/join', async (req, res) => {
  const { id } = req.params;
  try{
    const [rows] = await pool.execute('SELECT current_players, max_players FROM rooms WHERE id = ?', [id]);
    if(rows.length === 0) return res.status(404).json({ok: false, error: 'Room not found'});

    const room = rows[0];
    if(room.current_players >= room.max_players) {
      return res.status(400).json({ok: false, error: 'Room is full'});
    }

    await pool.execute('UPDATE rooms SET current_players = current_players + 1, updated_at = NOW() WHERE id = ?', [id]);
    return res.json({ ok: true });
  }catch(err){
    console.error(err);
    return res.status(500).json({ ok: false, error: err.message });
  }
});

// 更新房间武将列表
app.put('/api/rooms/:id/heroes', async (req, res) => {
  const { id } = req.params;
  const { heroes } = req.body || {};

  console.log('收到更新武将列表请求:', { roomId: id, heroes });

  if(!Array.isArray(heroes)){
    return res.status(400).json({ok: false, error: 'heroes must be an array'});
  }

  try{
    // 检查房间是否存在
    const [roomRows] = await pool.execute('SELECT id FROM rooms WHERE id = ?', [id]);
    console.log('查询房间结果:', roomRows);
    if(roomRows.length === 0) return res.status(404).json({ok: false, error: 'Room not found'});

    // 删除该房间现有的武将关联
    await pool.execute('DELETE FROM room_heroes WHERE room_id = ?', [id]);

    // 插入新的武将列表
    for(let i = 0; i < heroes.length; i++){
      const heroId = heroes[i];
      if(heroId != null && Number.isFinite(Number(heroId))){
        await pool.execute(
          'INSERT INTO room_heroes (room_id, hero_id, position, created_at) VALUES (?, ?, ?, NOW())',
          [id, heroId, i]
        );
      }
    }

    console.log('武将列表更新成功');
    return res.json({ok: true});
  }catch(err){
    console.error('更新武将列表错误:', err);
    return res.status(500).json({ok: false, error: err.message});
  }
});

// 用户选择管理 API
// 获取房间的所有选择
app.get('/api/choices/:roomId', async (req, res) => {
  const { roomId } = req.params;
  try{
    const [rows] = await pool.execute('SELECT * FROM user_choices WHERE room_id = ?', [roomId]);
    return res.json({ok: true, data: rows});
  }catch(err){
    console.error(err);
    return res.status(500).json({ok: false, error: err.message});
  }
});

// 提交/更新用户选择
app.post('/api/choices', async (req, res) => {
  const { room_id, user_id, hero_id, role } = req.body || {};
  if (!room_id || !user_id || !hero_id || !role) {
    return res.status(400).json({ ok: false, error: 'room_id, user_id, hero_id, and role are required' });
  }

  try{
    // 检查是否已存在
    const [existing] = await pool.execute(
      'SELECT id FROM user_choices WHERE room_id = ? AND user_id = ? AND hero_id = ?',
      [room_id, user_id, hero_id]
    );

    if(existing.length > 0){
      // 更新
      await pool.execute(
        'UPDATE user_choices SET role = ?, submitted = TRUE, updated_at = NOW() WHERE id = ?',
        [role, existing[0].id]
      );
      return res.json({ ok: true, action: 'updated' });
    } else {
      // 插入
      const sql = 'INSERT INTO user_choices (room_id, user_id, hero_id, role, submitted, created_at, updated_at) VALUES (?, ?, ?, ?, TRUE, NOW(), NOW())';
      const [result] = await pool.execute(sql, [room_id, user_id, hero_id, role]);
      return res.json({ ok: true, action: 'created', id: result.insertId });
    }
  }catch(err){
    console.error(err);
    return res.status(500).json({ ok: false, error: err.message });
  }
});

const port = process.env.PORT || 3000;
app.listen(port, ()=>{
  console.log(`Server listening on http://localhost:${port}`);
  console.log('Static files available under /static (for example: /static/index.html)');
});
